package ca.etsmtl.log430.lab3.systemB;

import java.io.PipedWriter;

/**
 * This class contains the main method for assignment 3. The program
 * consists of these files:<br><br>
 * 
 * 1) SystemInitialize: instantiates all filters and pipes, starts all filters.<br>
 * 2) FileReaderFilter: reads input file and sends each line to its  pipe.<br>
 * 3) StatusFilter: separates the input stream in two project types (REG, CRI) and writes
 *    lines to the appropriate  pipe.<br>
 * 4) StateFilter: determines if an entry contains a particular state specified
 *    at instantiation. If so, sends the whole line to its  pipe.<br>
 * 5) MergeFilter: accepts inputs from 2 input pipes and writes them to its  pipe.<br>
 * 6) FileWriterFilter: sends its input stream to a text file.<br><br>
 * 
 * Pseudo Code:
 * <pre>
 * instantiate all filters and pipes
 * start FileReaderFilter
 * start StatusFilter
 * start StateFilter for RIS
 * start StateFilter for DIF
 * start MergeFilter
 * start FileWriterFilter
 * </pre>
 * 
 * Running the program:
 * <pre>
 * java SystemInitialize InputFile File > DebugFile
 * 
 * SystemInitialize - Program name
 * InputFile - Text input file (see comments below)
 * File - Text  file with students
 * DebugFile - Optional file to direct debug statements
 * </pre>
 * 
 * @author A.J. Lattanze
 */

public class SystemInitialize {

	public static void main(String argv[]) {
		// Let's make sure that input and  files are provided on the
		// command line

		if (argv.length != 3) {

			System.out
					.println("\n\nNombre incorrect de parametres d'entree. Utilisation:");
			System.out
					.println("\njava SystemInitialize <fichier d'entree> <fichier de sortie> <fichier de sortie2>");

		} else {
			// These are the declarations for the pipes.
			PipedWriter reader = new PipedWriter();
			PipedWriter statusREG = new PipedWriter();
			PipedWriter statusCRI = new PipedWriter();
			PipedWriter rate = new PipedWriter();
			PipedWriter rateOthers = new PipedWriter();
			PipedWriter stateRIS = new PipedWriter();
			PipedWriter stateRISOthers = new PipedWriter();
			PipedWriter stateDIF = new PipedWriter();
			PipedWriter stateOthers = new PipedWriter();
			PipedWriter selected1 = new PipedWriter();
			PipedWriter others1 = new PipedWriter();
			
			PipedWriter stateRIS2 = new PipedWriter();
			PipedWriter stateOthers2 = new PipedWriter();
			PipedWriter rateCRI2 = new PipedWriter();
			PipedWriter rateOthers2 = new PipedWriter();
			PipedWriter rateOthersCRI2 = new PipedWriter();
			PipedWriter rate2 = new PipedWriter();
			PipedWriter selected2 = new PipedWriter();
			PipedWriter others2 = new PipedWriter();
			
			PipedWriter selected = new PipedWriter();
			PipedWriter others = new PipedWriter();
			
			// Instantiate Filter Threads
			
			
			Thread fileReaderFilter = new FileReaderFilter(argv[0], reader);
			Thread statusFilter = new StatusFilter(reader, statusREG, statusCRI);
			
			// 1. Keep only REG Status Project, < 50%
			Thread rateFilter1 = new RateFilter(50, "INF", statusREG, rate, rateOthers);
			
			// Looking for RIS and DIF state Project
			Thread stateFilter1 = new StateFilter("RIS", rate, stateRIS, stateRISOthers);
			Thread stateFilter2 = new StateFilter("DIF", stateRISOthers, stateDIF, stateOthers);
			
			// Merging other projects
			Thread mergeFilter1 = new MergeFilter(stateOthers, rateOthers, others1);
			// Merging results
			Thread mergeFilter2 = new MergeFilter(stateRIS, stateDIF, selected1);
			
			
			//2. Keep only CRI Status with RIS State
			Thread stateFilter3 = new StateFilter("RIS", statusCRI, stateRIS2, stateOthers2);
			//Keep only CRI rates equal to 25
			Thread rateFilter2 = new RateFilter(25, "EG", stateRIS2, rateCRI2, rateOthersCRI2);
			//Keep the others that are > 75
			Thread rateFilter3 = new RateFilter(75, "SUP", stateOthers2, rate2, rateOthers2);
			//Merge wanted results
			Thread mergeFilter3 = new MergeFilter(rateCRI2, rate2, selected2);
			//Merge others
			Thread mergeFilter4 = new MergeFilter(rateOthersCRI2, rateOthers2, others2);
			
			//Merge 1 + 2
			Thread mergeFilter5 = new MergeFilter(selected1, selected2, selected);
			Thread mergeFilter6 = new MergeFilter(others1, others2, others);
			
			
			Thread fileWriterFilter = new FileWriterFilter(argv[1], selected);
			Thread fileWriterFilter2 = new FileWriterFilter(argv[2], others);
			
			//
			// Start the threads
			//
			fileReaderFilter.start();
			statusFilter.start();
			rateFilter1.start();
			stateFilter1.start();
			stateFilter2.start();
			mergeFilter1.start();
			mergeFilter2.start();
			
			stateFilter3.start();
			rateFilter2.start();
			rateFilter3.start();
			mergeFilter3.start();
			mergeFilter4.start();
			
			mergeFilter5.start();
			mergeFilter6.start();
			
			fileWriterFilter.start();
			fileWriterFilter2.start();
			
		}  // if
		
	} // main
	
} // SystemInitialize